//
// Table.cpp for 206observ in /home/morel_t//Rendu/maths/206observ
// 
// Made by thomas morel
// Login   <morel_t@epitech.net>
// 
// Started on  Mon May  7 11:07:21 2012 thomas morel
// Last update Mon May  7 14:35:52 2012 thomas morel
//

#include	<sstream>
#include	<cmath>
#include	"Table.hh"

Table::Table(const std::vector<std::string> &file)
{
  if (checkFile(file))
    getValues(file);
}

Table::~Table()
{
}

double		Table::moyenneArithmetique() const
{
  double	div = 0;
  double	result = 0;

  for (int i = 0; i < this->nbMax_; ++i)
    {
      result += this->observations_[i] * this->effectifs_[i];
      div += this->effectifs_[i];
    }
  return (result / div);
}

double		Table::moyenneQuadratique() const
{
  double	div = 0;
  double	result = 0;

  for (int i = 0; i < this->nbMax_; ++i)
    {
      result += pow(this->observations_[i], 2) * this->effectifs_[i];
      div += this->effectifs_[i];
    }
  return (sqrt(result / div));
}

double		Table::moyenneGeometrique() const
{
  double	div = 0;
  double	result = 1;

  for (int i = 0; i < this->nbMax_; ++i)
    {
      result *= pow(this->observations_[i], this->effectifs_[i]);
      div += this->effectifs_[i];
    }
  return (pow(result, (1.0 / div)));
}

double		Table::moyenneHarmonique() const
{
  double	div = 0;
  double	result = 0;

  for (int i = 0; i < this->nbMax_; ++i)
    {
      result += (1.0 / this->observations_[i]) * this->effectifs_[i];
      div += this->effectifs_[i];
    }
  return (div / result);
}

double		Table::mediane() const
{
  int		i = 0;
  double	result = 0;
  int		quarry = 0;

  for (i = 0; i < this->nbMax_; ++i)
    quarry += this->effectifs_[i];
  if (!(quarry % 2))
    {
      quarry /= 2;
      for (i = 0; result <= quarry; ++i)
	result += this->effectifs_[i];
      return (this->observations_[i - 1]);
    }
  return (this->observations_[(nbMax_ / 2)]);
}

double		Table::mode() const
{
  int		tmp = 0;
  int		index = 0;

  for (int i = 0; i < this->nbMax_; ++i)
    {
      if (tmp < this->effectifs_[i])
	{
	  tmp = this->effectifs_[i];
	  index = i;
	}
    }
  return (this->observations_[index]);
}

double		Table::variance() const
{
  double	div = 0;
  double	result = 0;

  for (int i = 0; i < this->nbMax_; ++i)
    {
      result += pow(this->observations_[i], 2) * this->effectifs_[i];
      div += this->effectifs_[i];
    }
  return ((result / div) - pow(moyenneArithmetique(), 2));
}

double		Table::ecartType() const
{
  return (sqrt(variance()));
}

double		Table::ecartMoyen() const
{
  double	div = 0;
  double	result = 0;

  for (int i = 0; i < nbMax_; ++i)
    {
      result += fabs((this->observations_[i] - moyenneArithmetique()) * this->effectifs_[i]);
      div += this->effectifs_[i];
    }
  return (result / div);
}

double		Table::ecartMedian() const
{
  double	div = 0;
  double	result = 0;

  for (int i = 0; i < nbMax_; ++i)
    {
      result += fabs((this->observations_[i] - mediane()) * this->effectifs_[i]);
      div += this->effectifs_[i];
    }
  return (result / div);
}

bool		Table::checkFile(const std::vector<std::string> &file) const
{
  if (file.size() < 2)
    return (false);
  return (true);
}

void		Table::getValues(const std::vector<std::string> &file)
{
  int						obs;
  int						eff;
  std::vector<std::string>::const_iterator	it = file.begin();
  std::stringstream				stream(*it);

  stream >> this->nbMax_;
  ++it;
  for (; it != file.end(); ++it)
    {
      std::stringstream	stream(*it);

      stream >> obs;
      stream >> eff;
      this->observations_.push_back(obs);
      this->effectifs_.push_back(eff);
    }
}
